import qs from 'qs'
import { Encrypt, Decrypt } from '@/utils/auth'
import PsMessage from '@/components/message/index'
import store from '@/store'

// import cacheToken from '@/cache-list/cache-token'
// import cacheSystem from '@/cache-list/cache-system'
const VUE_APP_BASE_API = process.env.VUE_APP_BASE_API

let securityPubkey = ''
// let localSystem = {}
// let localToken = ''

export function setContextType (option, type = 'application/json;charset=utf-8') {
  if (!option.headers) return
  if (option.form) {
    // eslint-disable-next-line sonarjs/no-duplicate-string
    option.headers.set('content-type', 'application/x-www-form-urlencoded;charset=utf-8')
    return
  }
  if (option.headers.has('content-type') || option.noSetType) return
  option.headers.set('content-type', type)
}

function encryptBody (body, option) {
  if (!option.isEncrypt) return body
  const encryptData = Encrypt(body, securityPubkey)
  option.headers && option.headers.append('Secure', 'web')
  option.headers && option.headers.append('SecurityKey', encryptData.encryptKey)
  option.encryptKey = encryptData.key
  if (option.method !== 'GET') {
    option.headers && option.headers.append('SecurityBody', encryptData.crc)
    return encryptData.encrypt
  }
  return body
}

export function transformBody (option, body) {
  if (['GET', 'HEAD'].includes(option.method)) {
    return `${qs.stringify(body)}`
  }
  if (option.headers?.get('content-type')?.includes('application/json')) {
    return JSON.stringify(body)
  }
  if (option.headers?.get('content-type')?.includes('application/x-www-form-urlencoded')) {
    return qs.stringify(body)
  }
  return body
}

export async function setUserStatusResponse (status, body, options) {
  // if (status === 401 && body?.code === 401 && options?.reauth >)
  if ((status === 401 && body?.code === 401) || body?.code === 401) {
    store.dispatch('user/resetUserInfo')
    PsMessage({ message: '当前用户状态已失效，请重新登录' })
  }
}

export function getDefaultHeaders (options) {
  // 默认headers
  const headers = options.headers || new Headers()
  if (options.pure) return headers

  if (!options.noAppId) {
    headers.append('AppId', store.getters.appInfo.appID)
    headers.append('UnionID', store.getters.appInfo.channel)
    headers.append('merchantId', 'keluomuai')
  }
  // 非用户侧得接口不需要这些header

  if (!options.user) {
    headers.append('Version', store.getters.appInfo.version)
  }

  if (!options.noToken && store.getters.token) {
    // 用户token信息
    if (options.user || options.authBear) headers.append('Authorization', `Bearer ${store.getters.token}`)
    else headers.append('Token', `${store.getters.token}`)
  }
  return headers
}

export default async function fetchReqeust (method, url, data, option) {
  await initAppInfo()
  let options = {}
  if (option) options = option
  const headers = getDefaultHeaders(options)
  options.headers = headers
  options.method = method
  setContextType(options)

  if (['GET', 'HEAD'].includes(method)) {
    url = `${url}?${transformBody(options, data)}`
  } else {
    options.body = transformBody(options, data)
    options.body = encryptBody(options.body, options)
  }

  try {
    const res = await fetch(url, options)

    return [null, res]
  } catch (err) {
    return [err, null]
  }
}
const initPublicKey = async () => {
  if (securityPubkey) return
  const headers = new Headers()
  headers.append('Secure', 'HandShake')
  const { data } = await request('GET', `${VUE_APP_BASE_API}/api/v1/get_secure_pub`, null, {
    headers
  })
  securityPubkey = data?.data
}

export const initAppInfo = async () => {
  // localSystem = (await cacheSystem.getAsync()) || {}
  // localToken = (await cacheToken.getAsync()).token
}

const transformResponse = async (res, option) => {
  let data
  try {
    if (option?.isEncrypt) {
      const text = await res.text()
      data = Decrypt(text, option.encryptKey) || {}
    } else if (option?.responseType === 'blob') {
      data = await res.blob()
    } else if (option?.responseType === 'arraybuffer') {
      data = await res.arrayBuffer()
    } else if (option?.responseType === 'text') {
      data = await res.text()
    } else {
      data = await res.json()
    }
  } catch (e) {
    return data
  }
  return data
}

export async function request (method, url, data, option) {
  await initAppInfo()
  if (option?.isEncrypt) {
    await initPublicKey()
  }
  const [err, res] = await fetchReqeust(method, url, data, option)
  const header = res?.headers
  const statusCode = res?.status
  if (err) {
    return { error: err, data: null, header, statusCode }
  }
  const json = await transformResponse(res, option)
  // debugger
  setUserStatusResponse(statusCode, json)
  return { error: null, data: json, header, statusCode }
}
